package cn.xiaoming.car.server.service.impl;

import cn.xiaoming.car.pojo.order.pojo.entity.OrderTbl;
import cn.xiaoming.car.pojo.order.pojo.param.OrderTblUpdateParam;
import cn.xiaoming.car.server.IOrderService;
import cn.xiaoming.car.server.ex.ServiceException;
import cn.xiaoming.car.server.jsonresult.ServiceCode;
import cn.xiaoming.car.server.pojo.BackOrderInfo;
import cn.xiaoming.car.server.pojo.PayOrderInfo;
import cn.xiaoming.car.server.service.IPayService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;

import static cn.xiaoming.car.server.IOrderService.*;

@Slf4j
@Service
public class PayServiceImpl implements IPayService {

    @DubboReference
    IOrderService orderService;

    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    @Override
    public PayOrderInfo selectById(String uuid) {

        OrderTbl orderTbl = orderService.selectOrderById(uuid);
        if (orderTbl==null){
            throw new ServiceException(ServiceCode.ERR_PAY_FAIL,"获取订单信息失败，请稍后重试！");
        }

        PayOrderInfo orderInfo=new PayOrderInfo();

        Integer status = orderTbl.getStatus();

        //查询在订单中是否存在被订购的状态
        int count = orderService.selectPurchasedCountByCarId(orderTbl.getCarId(),orderTbl.getBuyerId());
        if (count>0){
            orderTbl.setStatus(EXPIRE);
            orderService.updateOrderTbl(orderTbl);
            throw new ServiceException(ServiceCode.ERR_BAD_REQUEST,"很抱歉，该车辆已被订购");
        }

        BigDecimal payMoney;
        String name;
        String body;
        String id;

        // 根据本次获取订单的状态，决定本次支付订单的支付金额
        if(status.equals(INITIAL)){
            //先从redis获取订单信息，如果为空， 则订单已经过期，无法继续支付
            if (!redisTemplate.hasKey(ORDER_KEY_ + orderTbl.getId())){
                throw new ServiceException(ServiceCode.ERR_PAY_FAIL,"订单已过期，无法支付");
            }
            id=orderTbl.getId()+"_firstPay";
            payMoney=orderTbl.getFirstMoney();
            name="这是订金支付，臭卖车的平台";
            body="不错，订了一台好车";
        }else if(status.equals(PAID_FIRST)){
            id=orderTbl.getId()+"_lastPay";
            payMoney=orderTbl.getLastMoney();
            name="这是尾款支付，臭卖车的平台";
            body="不错，买了一台Dream Car";
        }else {
            throw new ServiceException(ServiceCode.ERR_PAY_FAIL,"订单状态异常！");
        }

        orderInfo.setId(id)
                .setStatus(orderTbl.getStatus())
                .setBuyerId(orderTbl.getBuyerId())
                .setCarId(orderTbl.getCarId())
                .setSellerId(orderTbl.getSellerId())
                .setPayMoney(payMoney)
                .setName(name)
                .setBody(body);
        return orderInfo;
    }

    @Override
    public void backUpdateOrderInfo(BackOrderInfo backOrderInfo) {
        // 异步回调向订单模块提供数据，向数据库更新订单信息
        log.debug("来到回调参数：{}",backOrderInfo);

        String id="";
        id=backOrderInfo.getOutTradeNo().substring(0,backOrderInfo.getOutTradeNo().lastIndexOf("_"));
        log.debug("处理后的id：{}",id);

        OrderTblUpdateParam orderTblUpdateParam=new OrderTblUpdateParam();
        orderTblUpdateParam.setId(id);

        OrderTbl orderTbl = orderService.selectOrderById(id);
        backOrderInfo.setOrderState(orderTbl.getStatus());

        if (!backOrderInfo.getPayMoney().equals(backOrderInfo.getBuyerPayMoney())){
            throw new ServiceException(ServiceCode.ERR_PAY_FAIL,"支付订单信息异常，实付款与预付款金额不等！");
        }
        //  能来到这里说明肯定支付成功了，所以也视为成功的支付了订金，因为存在用户点击支付后已经在支付页面了，但刚好过期了
        //  这时候就会存在订单状态在已过期，但是又可以支付，所以，如果支付成功来到这里，即使订单状态为已过期，也视为支付成功了
        if (backOrderInfo.getOrderState().equals(INITIAL)||backOrderInfo.getOrderState().equals(EXPIRE)){
            orderTblUpdateParam
                    .setStatus(PAID_FIRST)
                    .setGmtFirstMoney(LocalDateTime.now());
            //覆盖原来在添加订单时存在redis中的数据，用于延时消费时判断订单是否已经被支付，否则在延时消费中修改该订单为过期状态
            String orderRedisKey=ORDER_KEY_+orderTbl.getId();//定义订单的key
            orderTbl.setStatus(PAID_FIRST);
            redisTemplate.opsForValue().set(orderRedisKey,orderTbl);
        }else if (backOrderInfo.getOrderState().equals(PAID_FIRST)){
            orderTblUpdateParam
                    .setStatus(PAID_LAST)
                    .setGmtLastMoney(LocalDateTime.now());
        }else{
            throw new ServiceException(ServiceCode.ERR_PAY_FAIL,"支付订单信息异常，订单状态异常！");
        }
        //远程调用更新数据库信息
        orderService.updateInfo(orderTblUpdateParam);
        log.debug("已经回调order（updateInfo），向数据库更新信息：{}",orderTblUpdateParam);
    }
}
